﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Text.RegularExpressions;

namespace com.crawler.common
{
    public class MyWebResponse
    {
        public Uri m_response_uri;
        public string m_content_type;
        public int m_content_length;
        public WebHeaderCollection m_headers;
        public string m_header;
        public Socket m_socket;
        public bool m_keep_alive;

        public void Connect(MyWebRequest i_request)
        {
            m_response_uri = i_request.m_request_uri;

            m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint remoteEP = new IPEndPoint(Dns.Resolve(m_response_uri.Host).AddressList[0], m_response_uri.Port);
            m_socket.Connect(remoteEP);
        }
        public void SendRequest(MyWebRequest i_request)
        {
            m_response_uri = i_request.m_request_uri;

            i_request.m_header = i_request.m_method + " " + m_response_uri.PathAndQuery + " HTTP/1.0\r\n" + i_request.m_headers;
            m_socket.Send(Encoding.ASCII.GetBytes(i_request.m_header));
        }
        public void SetTimeout(int i_timeout)
        {
            m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, i_timeout * 1000);
            m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, i_timeout * 1000);
        }
        public void ReceiveHeader()
        {
            m_header = "";
            m_headers = new WebHeaderCollection();

            byte[] bytes = new byte[10];
            while (m_socket.Receive(bytes, 0, 1, SocketFlags.None) > 0)
            {
                m_header += Encoding.ASCII.GetString(bytes, 0, 1);
                if (bytes[0] == '\n' && m_header.EndsWith("\r\n\r\n"))
                    break;
            }
            MatchCollection matches = new Regex("[^\r\n]+").Matches(m_header.TrimEnd('\r', '\n'));
            for (int n = 1; n < matches.Count; n++)
            {
                string[] strItem = matches[n].Value.Split(new char[] { ':' }, 2);
                if (strItem.Length > 0)
                    m_headers[strItem[0].Trim()] = strItem[1].Trim();
            }
            // check if the page should be transfered to another location
            if (matches.Count > 0 && (
                matches[0].Value.IndexOf(" 302 ") != -1 ||
                matches[0].Value.IndexOf(" 301 ") != -1))
                // check if the new location is sent in the "location" header
                if (m_headers["Location"] != null)
                {
                    try { m_response_uri = new Uri(m_headers["Location"]); }
                    catch { m_response_uri = new Uri(m_response_uri, m_headers["Location"]); }
                }
            m_content_type = m_headers["Content-Type"];
            if (m_headers["Content-Length"] != null)
                m_content_length = int.Parse(m_headers["Content-Length"]);
            m_keep_alive = (m_headers["Connection"] != null && m_headers["Connection"].ToLower() == "keep-alive") ||
                        (m_headers["Proxy-Connection"] != null && m_headers["Proxy-Connection"].ToLower() == "keep-alive");
        }
        public void Close()
        {
            m_socket.Close();
        }
       
    }
}
